*&---------------------------------------------------------------------*
*& Report ZFIR005
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zfir005.

INCLUDE zfi005top.
INCLUDE zfi005f01.

*----------------------------------------------------------------------*
*       初始化                                           *
*----------------------------------------------------------------------*
INITIALIZATION.
  is_functxt-icon_id   = icon_xls.
  is_functxt-icon_text = '下载模板'.
  sscrfields-functxt_01 = is_functxt.

*----------------------------------------------------------------------*
*          START-OF-SELECTION 主程序                     *
*----------------------------------------------------------------------*
START-OF-SELECTION.
  DATA: lt_excel  LIKE TABLE OF gs_record.
  PERFORM upload_data TABLES lt_excel USING p_file.
  PERFORM process_data.
  PERFORM disp_alv.

*&---------------------------------------------------------------------*
*& Form process_data
*&---------------------------------------------------------------------*
*& 权限
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM process_data .


  LOOP AT gt_out INTO gs_out.
    AUTHORITY-CHECK OBJECT 'F_BKPF_BUK'
    ID 'BUKRS' FIELD gs_out-bukrs.
    IF sy-subrc <> 0.
      gs_out-type = 'E'.
      gs_out-message = '@5C@ 您没有公司' && gs_out-bukrs && '的权限!'.
    ENDIF.
    AUTHORITY-CHECK OBJECT 'F_BKPF_BLA'
    ID 'BLART' FIELD gs_out-blart.
    IF sy-subrc <> 0.
      IF sy-subrc = 0.
        gs_out-type = 'E'.
        gs_out-message = '@5C@ 您没有订单类型' && gs_out-blart && '的权限!'.
      ENDIF.
    ENDIF.

    MODIFY gt_out FROM gs_out.
    CLEAR: gs_out.
  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form simulation_import_data
*&---------------------------------------------------------------------*
*& 模拟导入处理
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM simulation_import_data .

  DATA: ls_out LIKE gs_out,
        lt_out LIKE TABLE OF ls_out.
  DATA: lv_kunnr TYPE kunnr,
        lv_lifnr TYPE lifnr.

  IF gt_out[] IS NOT INITIAL.
    lt_out[] = gt_out[].
    SORT lt_out BY headid.
    DELETE ADJACENT DUPLICATES FROM lt_out COMPARING headid.

    SELECT bukrs,saknr
      INTO TABLE @DATA(lt_skb1)
      FROM skb1
      FOR ALL ENTRIES IN @gt_out
      WHERE bukrs = @gt_out-bukrs
      AND saknr = @gt_out-hkont.

    SORT lt_skb1 BY bukrs saknr.

    LOOP AT lt_out INTO ls_out.

      LOOP AT gt_out INTO gs_out WHERE headid = ls_out-headid.

        READ TABLE lt_skb1 INTO  DATA(ls_skb1) WITH KEY bukrs = gs_out-bukrs saknr = gs_out-hkont BINARY SEARCH.
        IF sy-subrc <> 0.
          gs_out-message = gs_out-message && '/' && '总账科目' && gs_out-hkont && '不存在!'.
          gs_out-type = 'E'.
        ENDIF.

        IF gs_out-type <> 'E'.
          PERFORM bapi_fill_document .
        ENDIF.
        CLEAR: gs_out.
      ENDLOOP.

      PERFORM bapi_check_document.

      LOOP AT lt_return INTO ls_return WHERE type CA 'AEX'.
        ls_out-type = ls_return-type.
        ls_out-message = ls_return-message && ls_out-message.
      ENDLOOP.
      IF ls_out-type = ''.
        ls_out-type = 'S'.
        ls_out-message = '凭证检查无错误!'.
      ENDIF.

      MODIFY gt_out FROM ls_out TRANSPORTING  type message WHERE headid = ls_out-headid.
      CLEAR: lt_return[],ls_return,lt_accountgl[],ls_accountgl.
      CLEAR: ls_out,ls_header,lv_item,ls_customer,lt_customer[],ls_vendor,lt_vendor[],ls_amount,lt_amount[],ls_extension2,lt_extension2[],ls_zexten,lt_accounttax[].
    ENDLOOP.

  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form formal_import_data
*&---------------------------------------------------------------------*
*& 正式导入处理
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM formal_import_data .
  DATA: ls_out LIKE gs_out,
        lt_out LIKE TABLE OF ls_out.

  IF lv_x = 'X'.
    lt_out[] = gt_out[].
    SORT lt_out BY headid.
    DELETE ADJACENT DUPLICATES FROM lt_out[] COMPARING headid.

    LOOP AT lt_out INTO ls_out WHERE type = 'S'.

      LOOP AT gt_out INTO gs_out WHERE headid = ls_out-headid..
        PERFORM bapi_fill_document . " 填充数据
        CLEAR: gs_out.
      ENDLOOP.
      " 创建凭证
      PERFORM bapi_creat_document.
      " 根据结果判断是否成功!
      LOOP AT lt_return INTO ls_return WHERE type = 'E'.
        ls_out-type = ls_return-type.
        ls_out-message = ls_return-message.
      ENDLOOP.

      IF ls_out-type = 'E'.
        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'
*       IMPORTING
*         RETURN        =
          .
      ELSE.
        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait = 'X'
*         IMPORTING
*           RETURN        =
          .
        READ TABLE lt_return INTO ls_return WITH KEY type = 'S' id  = 'RW' number = '605'.
        IF sy-subrc = 0.
          ls_out-belnr = ls_return-message_v2+0(10)." 会计凭证号码
          ls_out-message = '@5B@' && '创建成功!'.
        ENDIF.

      ENDIF.
      " 回写到内表
      MODIFY gt_out FROM ls_out TRANSPORTING  type message belnr  WHERE headid = ls_out-headid.

      CLEAR: lt_return[],ls_return,lt_accountgl[],ls_accountgl.
      CLEAR: ls_out,ls_header,lv_item,ls_customer,lt_customer[],ls_vendor,lt_vendor[],ls_amount,lt_amount[],ls_extension2,lt_extension2[],ls_zexten,lt_accounttax[].

    ENDLOOP.

  ELSE.
    MESSAGE i888(sabapdocu) WITH '请通过模拟导入检查数据!'.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form bapi_fill_document
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM bapi_fill_document.

  ls_header-username = sy-uname. " 用户名
  ls_header-header_txt =  gs_out-bktxt. " 抬头文本
  ls_header-comp_code = gs_out-bukrs.
  ls_header-doc_type = gs_out-blart. "
  ls_header-doc_date = gs_out-bldat . "凭证日期
  ls_header-fisc_year  = gs_out-budat+0(4).  "会计年度
  ls_header-pstng_date = gs_out-budat. " 过账日期
  ls_header-fis_period = gs_out-monat. " 期间
  ls_header-ref_doc_no = gs_out-xblnr. " 参考凭证
  ls_header-header_txt = gs_out-bktxt.
  ls_header-neg_postng = gs_out-xnegp.


  "行项目
  lv_item = lv_item + 1.

  IF gs_out-mwskz IS INITIAL.

    CASE gs_out-bschl.
      WHEN '40' OR '50'. "总账
        CLEAR: ls_accountgl.
        ls_accountgl-itemno_acc   = lv_item.
        ls_accountgl-gl_account   = gs_out-hkont. "总账科目
        ls_accountgl-tax_code     = gs_out-mwskz. " 税码
        ls_accountgl-item_text    = gs_out-sgtxt. "项目文本
        ls_accountgl-costcenter   = gs_out-kostl. "成本中心编号
        ls_accountgl-alloc_nmbr   = gs_out-zuonr. "分配号
        ls_accountgl-orderid      = gs_out-aufnr. "订单号
        ls_accountgl-material_long = gs_out-matnr.
        ls_accountgl-quantity = gs_out-menge.
        ls_accountgl-base_uom = gs_out-meins."基本计量单位
        ls_accountgl-plant = gs_out-werks.
        APPEND ls_accountgl TO lt_accountgl.
        CLEAR: ls_accountgl.

      WHEN '09' OR '19' OR '01' OR '11'.  " 客户
        CLEAR: ls_customer.

        CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
          EXPORTING
            input  = gs_out-newko
          IMPORTING
            output = ls_customer-customer.

        ls_customer-itemno_acc = lv_item.
        ls_customer-gl_account = gs_out-hkont.   "总账科目
        ls_customer-item_text  = gs_out-sgtxt.   "项目文本
        ls_customer-alloc_nmbr   = gs_out-zuonr. "分配号
        ls_customer-sp_gl_ind    = gs_out-umskz. "特别总帐标识 特殊总分类帐标志
        ls_customer-tax_code     = gs_out-mwskz. "
        ls_customer-bline_date    = gs_out-zfbdt. "到期日计算的基限日期

        APPEND ls_customer TO lt_customer.
        CLEAR: ls_customer.

      WHEN '29' OR '39' OR '21' OR '31'.  "供应商科目
        CLEAR: ls_vendor.
        CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
          EXPORTING
            input  = gs_out-newko
          IMPORTING
            output = ls_vendor-vendor_no.

        ls_vendor-itemno_acc   = lv_item.
        ls_vendor-gl_account   = gs_out-hkont. "总账科目
        ls_vendor-item_text    = gs_out-sgtxt. "项目文本
        ls_vendor-alloc_nmbr   = gs_out-zuonr. "分配号
        ls_vendor-sp_gl_ind    = gs_out-umskz. "特别总帐标识 特殊总分类帐标志
        ls_vendor-bline_date   = gs_out-zfbdt. "到期日计算的基限日期
        ls_vendor-tax_code     = gs_out-mwskz.
        APPEND ls_vendor TO lt_vendor.
        CLEAR: ls_vendor.
*    WHEN '70' OR '75'." 资产

      WHEN OTHERS.
    ENDCASE.

  ENDIF.
  "货币项目
  CASE gs_out-bschl.
    WHEN '40' OR '01' OR '09' OR '21' OR '29'." OR '70'.
      IF gs_out-waers = 'CNY'.
        ls_amount-amt_doccur = gs_out-wrbtr.  "金额
        ls_amount-itemno_acc = lv_item.
        ls_amount-currency   = 'CNY'.  "货币码
        IF gs_out-hwbas > 0.
          ls_amount-amt_base = gs_out-hwbas.
        ENDIF.

        APPEND ls_amount TO lt_amount.
        CLEAR: ls_amount.
      ELSE.
        ls_amount-amt_doccur = gs_out-dmbtr."wrbtr.  "金额
        ls_amount-curr_type  = '10'.
        ls_amount-itemno_acc = lv_item.
        ls_amount-currency   = 'CNY'.  "货币码
        IF gs_out-hwbas > 0.
          ls_amount-amt_base = gs_out-hwbas.
        ENDIF.
        APPEND ls_amount TO lt_amount.
        CLEAR: ls_amount.

        ls_amount-amt_doccur = gs_out-wrbtr."dmbtr.  "金额
        ls_amount-curr_type  = '00'.
        ls_amount-itemno_acc = lv_item.
        ls_amount-currency   = gs_out-waers.  "货币码
        IF gs_out-hwbas > 0.
          ls_amount-amt_base = gs_out-hwbas.
        ENDIF.
        APPEND ls_amount TO lt_amount.
        CLEAR: ls_amount.
      ENDIF.
    WHEN '50' OR '11' OR '19' OR '31' OR '39'." OR '75'.

      IF gs_out-waers = 'CNY'.
        ls_amount-amt_doccur = gs_out-wrbtr * -1.  "金额
        ls_amount-itemno_acc = lv_item.
        ls_amount-currency   = 'CNY'.  "货币码
        IF gs_out-hwbas > 0.
          ls_amount-amt_base = gs_out-hwbas.
        ENDIF.
        APPEND ls_amount TO lt_amount.
        CLEAR: ls_amount.

      ELSE.

        ls_amount-amt_doccur = gs_out-dmbtr * -1.  "金额
        ls_amount-curr_type  = '10'.
        ls_amount-itemno_acc = lv_item.
        ls_amount-currency   = 'CNY'.  "货币码
        IF gs_out-hwbas > 0.
          ls_amount-amt_base = gs_out-hwbas.
        ENDIF.
        APPEND ls_amount TO lt_amount.
        CLEAR: ls_amount.

        ls_amount-amt_doccur = gs_out-wrbtr * -1.  "金额
        ls_amount-curr_type  = '00'.
        ls_amount-itemno_acc = lv_item.
        ls_amount-currency   = gs_out-waers.  "货币码
        IF gs_out-hwbas > 0.
          ls_amount-amt_base = gs_out-hwbas.
        ENDIF.
        APPEND ls_amount TO lt_amount.
        CLEAR: ls_amount.
      ENDIF.
  ENDCASE.

  IF gs_out-mwskz IS  NOT INITIAL.
    ls_accounttax-itemno_acc      = lv_item.     "行项目号
   " ls_accounttax-acct_key = 'VST'.
    ls_accounttax-gl_account      = gs_out-hkont. "科目
    ls_accounttax-tax_code        = gs_out-mwskz.      "销售税代码
    ls_accounttax-direct_tax      = 'X'.           "标识: 直接税收过帐

    APPEND ls_accounttax TO lt_accounttax.
    CLEAR:ls_accounttax.
  ENDIF.



  CLEAR:ls_zexten.
  ls_extension2-structure  = 'ZBADI_ACC'.
  ls_zexten-posnr          = lv_item.
  IF gs_out-hwbas IS NOT INITIAL.
    ls_zexten-taxit          = 'X'.
  ENDIF.

  ls_zexten-rstgr          = gs_out-rstgr.
  ls_zexten-bschl          = gs_out-bschl.  "记帐代码.
  ls_zexten-xnegp          = gs_out-xnegp.  "反记帐
  ls_zexten-numpg          = gs_out-numpg.



  CALL METHOD cl_abap_container_utilities=>fill_container_c
    EXPORTING
      im_value               = ls_zexten
    IMPORTING
      ex_container           = ls_extension2+30
    EXCEPTIONS
      illegal_parameter_type = 1
      OTHERS                 = 2.

  APPEND ls_extension2 TO lt_extension2.
  CLEAR: ls_extension2,ls_zexten.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form bapi_check_document
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM bapi_check_document .

  CALL FUNCTION 'BAPI_ACC_DOCUMENT_CHECK'
    EXPORTING
      documentheader    = ls_header
*     CUSTOMERCPD       =
*     CONTRACTHEADER    =
    TABLES
      accountgl         = lt_accountgl
      accountreceivable = lt_customer
      accountpayable    = lt_vendor
      accounttax        = lt_accounttax
      currencyamount    = lt_amount
*     CRITERIA          =
*     VALUEFIELD        =
*     EXTENSION1        =
      return            = lt_return
*     PAYMENTCARD       =
*     CONTRACTITEM      =
      extension2        = lt_extension2
*     REALESTATE        =
*     ACCOUNTWT         =
    .

ENDFORM.
*&---------------------------------------------------------------------*
*& Form bapi_creat_document
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM bapi_creat_document .
  CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
    EXPORTING
      documentheader    = ls_header
*     CUSTOMERCPD       =
*     CONTRACTHEADER    =
    IMPORTING
      obj_type          = lv_awtype
      obj_key           = lv_awkey
      obj_sys           = lv_awsys
    TABLES
      accountgl         = lt_accountgl
      accountreceivable = lt_customer
      accountpayable    = lt_vendor
      accounttax        = lt_accounttax
      currencyamount    = lt_amount
*     CRITERIA          =
*     VALUEFIELD        =
*     EXTENSION1        =
      return            = lt_return
*     PAYMENTCARD       =
*     CONTRACTITEM      =
      extension2        = lt_extension2
*     REALESTATE        =
*     ACCOUNTWT         =
    .

ENDFORM.